#include <iostream>
#include "ContactException.h"
#include "httplib.h"
#include "add_contact.pb.h"
using namespace httplib;

void menu()
{
	std::cout << "-----------------------------------------------------" << std::endl
			  << "--------------- 请选择对通讯录的操作 ----------------" << std::endl
			  << "------------------ 1、新增联系人 --------------------" << std::endl
			  << "------------------ 2、删除联系人 --------------------" << std::endl
			  << "------------------ 3、查看联系人列表 ----------------" << std::endl
			  << "------------------ 4、查看联系人详细信息 ------------" << std::endl
			  << "------------------ 0、退出 --------------------------" << std::endl
			  << "-----------------------------------------------------" << std::endl;
}

void build(add_contact::AddContactRequest* req)
{
	std::cout << "请输入联系人姓名：";
	std::string name;
	getline(std::cin, name);
	req->set_name(name);
	std::cout << "请输入联系人年龄：";
	int age;
	std::cin >> age;
	req->set_age(age);
	std::cin.ignore(256, '\n'); // 如果不清理，缓冲区中还有 \n 后续getline(std::cin,number);就直接把 \n 输入给number，就触发了break
	for (int i = 1;; i++)
	{
		std::cout << "请输入联系人电话" << i << "(按回车就退出)：";
		std::string number;
		getline(std::cin, number);
		if (number.empty())
		{
			break;
		}
		add_contact::AddContactRequest_Phone* phone = req->add_phone();
		phone->set_number(number);
		std::cout << "电话类型：1.移动电话 2.固定电话: ";
		int type;
		std::cin >> type;
		std::cin.ignore(256, '\n');
		switch (type)
		{
		case 1:
			phone->set_type(add_contact::AddContactRequest_Phone_PhoneType::AddContactRequest_Phone_PhoneType_MP);
			break;
		case 2:
			phone->set_type(add_contact::AddContactRequest_Phone_PhoneType::AddContactRequest_Phone_PhoneType_TEL);
			break;
		default:
			std::cout << "非法选择，使用默认值！" << std::endl;
			break;
		}
	}
}

void AddContact()
{
	Client cli("127.0.0.0",8080);
	// 构造req
	add_contact::AddContactRequest req;
	build(&req);

	// 序列化req
	std::string req_str;
	if(!req.SerializeToString(&req_str))
	{
		throw ContactException("序列化失败");
	}

	// 发起post调用
	auto res = cli.Post("/contacts/add",req_str,"application/protobuf");
	if(!res)
	{
		std::string err_desc;
		err_desc.append("/contacts/add ,连接失败！错误信息：").append(httplib::to_string(res.error()));
		throw ContactException(err_desc); 
	}
	// 反序列化 resp
	add_contact::AddContactResponse resp;
	bool parse = resp.ParseFromString(res->body);
	if(res->status != 200 && parse == false)
	{
		std::string err_desc;
		err_desc.append("/contacts/add ,调用失败！错误信息：").append(std::to_string(res->status))
		.append("(").append(res->reason).append(")");
		throw ContactException(err_desc); 
	}
	else if(res->status != 200)
	{
		std::string err_desc;
		err_desc.append("/contacts/add ,调用失败！错误信息：").append(std::to_string(res->status))
		.append("(").append(res->reason).append(")").append("错误原因：").append(resp.error());
		throw ContactException(err_desc); 
	}
	else if(!resp.success())
	{
		std::string err_desc;
		err_desc.append("/contacts/add ,调用失败！错误信息：").append(resp.error());
		throw ContactException(err_desc); 
	}
	// 打印
	std::cout << "新增练习人成功,uid为：" << resp.uid() << std::endl;
}

int main()
{
	enum OPTION
	{
		QUIT = 0,
		ADD,
		DEL,
		FIND_ALL,
		FIND_ONE

	};
	while (true)
	{
		menu();
		std::cout << "---请选择：";
		int choose;
		std::cin >> choose;
		std::cin.ignore(256, '\n');
		try
		{
			switch (choose)
			{
			case OPTION::QUIT:
				std::cout << "程序退出" << std::endl;
				return 0;
			case OPTION::ADD:
				AddContact();
				break;
			case OPTION::DEL:
			case OPTION::FIND_ALL:
			case OPTION::FIND_ONE:
			default:
				std::cout << "选择有误" << std::endl;
				break;
			}
		}
		catch (const ContactException &e)
		{
			std::cout << "---->操作通讯录发送异常" << std::endl 
				<< "----->异常的信息：" << e.what();
			std::cerr << e.what() << '\n';
		}
	}
	return 0;
}



// int main()
// {
// 	Client cli("127.0.0.0",8080);
// 	Result res1 = cli.Post("/test-post");
// 	if(res1->status == 200)
// 	{
// 		std::cout << "掉用post成功" << std::endl;
// 	}
// 	Result res2 = cli.Get("/test-get");
// 	if(res2->status == 200)
// 	{
// 		std::cout << "掉用get成功" << std::endl;
// 	}
// 	return 0;
// }